using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;

using DataTransferObject;
using Business;

namespace Presentation
{
    public partial class FrmDocGia : Form
    {
        BindingSource bs = new BindingSource();
        clsDocGiaDTO DocGiaDTO = new clsDocGiaDTO();
        clsLoaiDGBUS LoaiDGBUS = new clsLoaiDGBUS();
        clsQuanTriBUS QuanTriBUS = new clsQuanTriBUS();
        DataTable tbl = new DataTable();

        DataTable dtThayDoiQuyDinh = new DataTable();
        clsThayDoiQuyDinhBUS ThayDoiQuyDinhBUS = new clsThayDoiQuyDinhBUS();
        clsThayDoiQuyDinhDTO ThayDoiQuyDinhDTO = new clsThayDoiQuyDinhDTO();
        object[] obj = new object[10];

        public FrmDocGia()
        {
            InitializeComponent();
        }

        #region Phương thức đưa dữ liệu lên form.

        //Phương thức đưa dữ liệu lên form.
        private void LoadForm()
        {
            HienThiTextBox(false);
            btnluu.Enabled = false;
            btnchonhinh.Enabled = false;
            //btntim.Enabled = false;

            bs.DataSource = QuanTriBUS.DocGiaBUS.DanhSachDocGiaReference();
            bdndocgia.BindingSource = bs;
            dgvdocgia.DataSource = bs;
            TaoCotGridView();
            LoadLoaiDG();

            //Lấy table Thay đổi quy định.
            dtThayDoiQuyDinh = ThayDoiQuyDinhBUS.DanhSachThayDoiQuyDinh();
            obj = dtThayDoiQuyDinh.Rows[0].ItemArray;
            ThayDoiQuyDinhDTO.TuoiToiDa = (int) obj[0];
            ThayDoiQuyDinhDTO.TuoiToiThieu = (int) obj[1];
            ThayDoiQuyDinhDTO.ThoiHanThe = (int) obj[2];
            ThayDoiQuyDinhDTO.SoNgayMuonToiDa = (int) obj[3];
            ThayDoiQuyDinhDTO.SoSachMuonToiDa = (int) obj[4];
            ThayDoiQuyDinhDTO.TienPhatSachTre =Convert.ToInt64(obj[5]);
        }

        private void LoadLoaiDG()
        {
            DataTable dt = new DataTable();
            dt = LoaiDGBUS.DanhSachLoaiDG();
            cboloaidg.DataSource = dt;
            cboloaidg.DisplayMember = "TENLDG";
            cboloaidg.ValueMember = "MALDG";

            txtngaylapthe.Enabled = false;
            txtngayhethan.Enabled = false;
        }

        #endregion

        #region Phương thức lấy hình
        
        private void LayHinh()
        {
            DialogResult dlr = new DialogResult();
            openfdl.InitialDirectory = Application.StartupPath;
            dlr = openfdl.ShowDialog();
            string filename;

            try
            {
                if (dlr != DialogResult.Cancel)
                {
                    String url;
                    url = Application.StartupPath + @"\HinhDocGia\" + Path.GetFileName(openfdl.FileName);
                    pchinh.ImageLocation = url; //Gán hình vào PictureBox.
                    filename = openfdl.FileName;

                    int vitri = 0;
                    vitri = filename.LastIndexOf(@"\");
                    filename = filename.Remove(0, vitri + 1);
                    
                    //Nếu hình ko tồn tại trong thư mục hiện hành hình copy hình vào thư mục hiện hành.
                    if (!File.Exists(Application.StartupPath + @"\HinhDocGia\" + Path.GetFileName(openfdl.FileName)))
                        File.Copy(openfdl.FileName, Application.StartupPath + @"\HinhDocGia\" + Path.GetFileName(openfdl.FileName), true);
                }
            }
            catch
            {
                DevComponents.DotNetBar.MessageBoxEx.Show("-Hình đang được ứng dụng khác sử dụng!!\n\n-Có thể: \n\n  +Copy hình sang thư mục khác và thử lại\n\n  +Hoặc chọn hình khác",
                                                     "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);                                                    
            }
        }

        #endregion

        #region Phương thức đặt các ngày mặc định.

        private void SetDefaultDate()
        {
            txtngaysinh.Text = Convert.ToString(new DateTime(DateTime.Today.Year - ThayDoiQuyDinhDTO.TuoiToiThieu, 1, 1));
            txtngaylapthe.Text = Convert.ToString(DateTime.Today);
            txtngayhethan.Text = Convert.ToString(new DateTime(DateTime.Today.Year, DateTime.Today.Month + ThayDoiQuyDinhDTO.ThoiHanThe, DateTime.Today.Day));
        }
        #endregion

        #region Các phương thức tạo mã tự động

        public String DinhdangMACH(String MACH)
        {
            if (MACH.Length == 1)
                MACH = "TL00" + MACH;
            else if (MACH.Length == 2)
                MACH = "TL0" + MACH;
            else if (MACH.Length == 3)
                MACH = "TL" + MACH;
            return MACH;
        }

        private int TimMaCauHoi()
        {
            int sl = 1;
            int dem = 0;
            tbl = QuanTriBUS.DocGiaBUS.DanhSachDocGia();
            foreach (DataRow dr in tbl.Rows)
            {
                int ma1 = Convert.ToInt16(Tim_CatChuoi(dr["MATHE"].ToString()));
                dem++;
                int ma2 = Convert.ToInt16(Tim_CatChuoi(dr["MATHE"].ToString()));

                if (dem != ma2)
                {
                    return dem;
                }
                else
                {
                    sl++;
                }

            }
            return sl;
        }


        public String Tim_CatChuoi(String Chuoicantim)
        {
            int vitri = 0;
            vitri = Chuoicantim.IndexOf(Chuoicantim, 0);
            if (vitri != -1)
                Chuoicantim = Chuoicantim.Remove(0, 2);
            return Chuoicantim;
        }

        #endregion

        #region Các phương thức thêm, sửa, xóa

        //Phương thức sửa độc giả.
        private void SuaDocGia()
        {
            DocGiaBUSResult rs;
            bool check;

            try
            {
                DocGiaDTO = new clsDocGiaDTO(); //Khởi tạo đối tượng.
                //--------------------------------

                //Kiểm tra tổng nợ có phải số.
                check = false;
                check = KiemTraTongNoLaSo(txttongno.Text.Trim());
                if (check == false)
                    return;

                //Nếu textbox tổng nợ rỗng thì cho nó bằng 0.
                if (txttongno.Text.Trim().Equals(""))
                    txttongno.Text = "0";

                //Lấy dữ liệu.
                DocGiaDTO.MaThe = txtmathe.Text;
                DocGiaDTO.HoTen = txthoten.Text.Trim();

                DocGiaDTO.NgaySinh = Convert.ToDateTime(txtngaysinh.Text); 
                DocGiaDTO.GioiTinh = cbogioitinh.SelectedItem.ToString();
                DocGiaDTO.DiaChi = txtdiachi.Text.Trim();
                DocGiaDTO.NgayLapThe = Convert.ToDateTime(txtngaylapthe.Text);
                DocGiaDTO.NgayHetHan = Convert.ToDateTime(txtngayhethan.Text);
                DocGiaDTO.TinhTrangNo = cbotinhtrang.SelectedItem.ToString();
                DocGiaDTO.MaLDG = cboloaidg.SelectedValue.ToString();

                //Lấy hình.
                if (pchinh.ImageLocation != null)
                {
                    int HinhDocGia;
                    String filename;

                    filename = pchinh.ImageLocation;
                    HinhDocGia = filename.IndexOf("HinhDocGia");
                    DocGiaDTO.HinhAnh = pchinh.ImageLocation.Substring(HinhDocGia);
                }
                else
                {
                    DocGiaDTO.HinhAnh = "";
                }
                
                DocGiaDTO.TongNo = Convert.ToInt64(txttongno.Text.Trim());
                //--------------------------------   

                //Kiểm tra tổng nợ âm.
                check = false;
                check = KiemTraTongNoAm(DocGiaDTO);
                if (check == false)
                    return;

                //Kiểm tra dữ liệu rỗng.
                check = false;
                check = CheckEmpty(DocGiaDTO);
                if (check == false)
                    return;

                //Kiểm tra quy định tuổi.
                check = false;
                check = KiemTraQuyDinhTuoi(DocGiaDTO);
                if (check == false)
                    return;

                rs = QuanTriBUS.DocGiaBUS.SuaDocGia(DocGiaDTO); //Gọi phượng thức sửa dữ liệu.
                if (rs == DocGiaBUSResult.OK) //Nếu sửa thành công.
                    DevComponents.DotNetBar.MessageBoxEx.Show("Đã cập nhật thành công!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                else //Sửa thất bại.
                    DevComponents.DotNetBar.MessageBoxEx.Show(this, "Không cập nhật được!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                RefreshForm(); //Refresh form.
                btnsua.Text = "Sửa";
            }
            catch (Exception ex)
            {
                DevComponents.DotNetBar.MessageBoxEx.Show(this, ex.Message, "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        //Phương thức xóa độc giả.
        private void XoaDocGia()
        {
            DialogResult dlg = new DialogResult(); //Hỏi trước khi xóa.
            dlg = DevComponents.DotNetBar.MessageBoxEx.Show(this, "Chắc chắn xóa không ?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Error);
            if (dlg == DialogResult.Yes) //Nếu chọn xóa.
            {
                DocGiaBUSResult rs;

                rs = QuanTriBUS.DocGiaBUS.XoaDocGia(DocGiaDTO); //Gọi phương thức xóa.
                if (rs == DocGiaBUSResult.OK) //Nếu xóa thành công.
                    DevComponents.DotNetBar.MessageBoxEx.Show(this, "Xóa thành công!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                else //Nếu xóa thất bại.
                    DevComponents.DotNetBar.MessageBoxEx.Show("Không xóa được!\n\n-Có thể có ít nhất 1 quyển sách thuộc độc giả này.", "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
                RefreshForm(); //Refresh form.
            }
        }
        #endregion

        #region Các phương thức kiểm tra, refresh data

        //Phương thức kiểm tra quy định tuổi.
        private bool KiemTraQuyDinhTuoi(clsDocGiaDTO obj)
        {
            ThayDoiQuyDinhBUSResult rs = QuanTriBUS.DocGiaBUS.KiemTraTuoi(obj);
            if (rs == ThayDoiQuyDinhBUSResult.TUOITOIDAERROR)
            {
                DevComponents.DotNetBar.MessageBoxEx.Show(this, "Độc giả phải nhỏ hơn hoặc bằng " + ThayDoiQuyDinhDTO.TuoiToiDa + " tuổi!\n\n-Lưu ý: Tuổi tính đến ngày", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                txtmathe.Focus();
                return false;
            }

            if (rs == ThayDoiQuyDinhBUSResult.TUOITOITHIEUERROR)
            {
                DevComponents.DotNetBar.MessageBoxEx.Show(this, "Độc giả phải lớn hơn hoặc bằng " + ThayDoiQuyDinhDTO.TuoiToiThieu + " tuổi!\n\n-Lưu ý: Tuổi tính đến ngày", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                txtmathe.Focus();
                return false;
            }
            return true;
        }

        //Phương thức kiểm tra dữ liệu rỗng.
        private bool CheckEmpty(clsDocGiaDTO obj)
        {
            DocGiaBUSResult rs;

            rs = QuanTriBUS.DocGiaBUS.KiemTraRong(obj); //Gọi hàm kiểm tra rỗng.
            if (rs == DocGiaBUSResult.MATHEERROR) //Nếu mã độc giả rỗng.
            {
                DevComponents.DotNetBar.MessageBoxEx.Show(this, "Mã độc giả không được rỗng!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                txtmathe.Focus();
                return false;
            }
            if (rs == DocGiaBUSResult.HOTENERROR) //Nếu tên độc giả rỗng.
            {
                DevComponents.DotNetBar.MessageBoxEx.Show(this, "Tên độc giả không được rỗng!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                txthoten.Focus();
                return false;
            }
            return true;
        }

        //Phương thức kiểm tra tổng nợ âm.
        private bool KiemTraTongNoAm(clsDocGiaDTO obj)
        {
            DocGiaBUSResult rs = QuanTriBUS.DocGiaBUS.TongNoAm(obj);

            if (rs == DocGiaBUSResult.TONGNOERROR) //Nếu tổng nơ < 0.
            {
                DevComponents.DotNetBar.MessageBoxEx.Show(this, "Tổng nợ không được nhỏ hơn 0!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                txttongno.Focus();
                return false;
            }
            return true;
        }

        //Phương thức kiểm tra tổng nợ là số.
        private bool KiemTraTongNoLaSo(String str)
        {
            if (!IsNumericRegEx(str))
            {
                DevComponents.DotNetBar.MessageBoxEx.Show(this, "Tổng nợ phải là số!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                txttongno.Focus();
                return false;
            }
            return true;
        }

        //Phương thức kiểm tra chuỗi có phải là số.
        private bool IsNumericRegEx(string str)
        {
            str = str.Trim();
            return (Regex.IsMatch(str, @"^[\+\-]?\d*\.?[Ee]?[\+\-]?\d*$"));
        }

        //Phương thức Refresh lại form.
        private void RefreshForm()
        {
            bs.DataSource = QuanTriBUS.DocGiaBUS.DanhSachDocGiaReference();
            bdndocgia.BindingSource = bs;

            HienThiTextBox(false);
            HienThiButton(false);
            btnsua.Enabled = true;
            btnxoa.Enabled = true;
        }
        #endregion

        #region Các phương thức ẩn-hiện Button, Textbox, Tạo cột cho DataGrid.

        //(Ẩn/hiện) Button.
        private void HienThiButton(bool dieukien)
        {
            btnsua.Enabled = dieukien;
            btnxoa.Enabled = dieukien;
            btnluu.Enabled = dieukien;
            btnchonhinh.Enabled = dieukien;
            //btntim.Enabled = dieukien;
        }

        //(Ẩn/hiện) TextBox.
        private void HienThiTextBox(bool a)
        {
            //txtmathe.Enabled = a;
            txthoten.Enabled = a;
            cbogioitinh.Enabled = a;
            txtngaysinh.Enabled = a;
            txtdiachi.Enabled = a;
            cboloaidg.Enabled = a;
            txttongno.Enabled = a;
            cbotinhtrang.Enabled = a;
        }

        //Xóa TextBox.
        private void XoaTextBox()
        {
            txthoten.Text = "";
        }

        //Tạo cột cho GridView
        private void TaoCotGridView()
        {
            dgvdocgia.Columns["MATHE"].HeaderCell.Value = "Mã độc giả";
            dgvdocgia.Columns["HOTEN"].HeaderCell.Value = "Tên độc giả";
            dgvdocgia.Columns["GIOITINH"].HeaderCell.Value = "Giới tính";
            dgvdocgia.Columns["NGAYSINH"].HeaderCell.Value = "Ngày sinh";
            dgvdocgia.Columns["NGAYLAPTHE"].HeaderCell.Value = "Ngày lập thẻ";
            dgvdocgia.Columns["NGAYHETHAN"].HeaderCell.Value = "Ngày hết hạn";
            dgvdocgia.Columns["DIACHI"].HeaderCell.Value = "Địa chỉ";
            dgvdocgia.Columns["TINHTRANGNO"].HeaderCell.Value = "Tình trạng nợ";
            dgvdocgia.Columns["TONGNO"].HeaderCell.Value = "Tổng nợ";
            dgvdocgia.Columns["TENLDG"].HeaderCell.Value = "Loại độc giả";
            dgvdocgia.Columns["HINHANH"].HeaderCell.Value = "Hình ảnh";
            dgvdocgia.Columns["HINHANH"].Visible = false;
        }
        #endregion

        #region Các phương thức thay đổi nút, chữ trên nút.

        //Khi nhấn nút sửa.
        private void NutSua()
        {
            btnsua.Text = "Hủy Bỏ";
            HienThiButton(false); //Ẩn tất cả các button.
            btnsua.Enabled = true;
            btnluu.Enabled = true;
            btnchonhinh.Enabled = true;
            //btntim.Enabled = true;

            HienThiTextBox(true); //Hiển thị các textbox.
            //txtmathe.Enabled = false;
        }

        //Khi nhấn nút hủy bỏ sửa.
        private void NutHuyBoSua()
        {
            btnsua.Text = "Sửa";
            HienThiButton(false); //Ẩn tất cả các button.
            btnsua.Enabled = true;
            btnxoa.Enabled = true;

            HienThiTextBox(false);
        }
        #endregion

        #region Các phương thức tìm độc giả trên GridView.
        
        //Phương thức tìm độc giả theo mã thẻ.
        private void TimDocGia()
        {
            String MaTheKhoa;

            try
            {
                MaTheKhoa = txtmathe.Text.Trim();
                for (int i = 0; i < dgvdocgia.Rows.Count; i++)
                {
                    String MaTheTemp;
                    DataGridViewRow row = new DataGridViewRow();
                    DataGridViewCell cell;

                    row = dgvdocgia.Rows[i];
                    cell = row.Cells["MaThe"];
                    MaTheTemp = cell.Value.ToString(); //Lấy mã thẻ độc giả của từng dòng.
                    if (MaTheTemp.StartsWith(MaTheKhoa))
                    {
                        BoChonTatCa(); //Bỏ chọn tất cả các dòng trong gridview.
                        bs.Position = i;
                        return;
                    }
                }
                DevComponents.DotNetBar.MessageBoxEx.Show(this, "Không tìm thấy độc giả!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            catch
            {
                DevComponents.DotNetBar.MessageBoxEx.Show(this, "Không tìm thấy độc giả!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

        }

        //Phương thức bỏ chọn tất cả các dòng trong gridview.
        private void BoChonTatCa()
        {
            foreach (DataGridViewRow row in dgvdocgia.Rows)
            {
                row.Selected = false;
            }
        }
        #endregion        

        //Events.
        #region Các phương thức của các sự kiện trên form.

        private void FrmDocGia_Load(object sender, EventArgs e)
        {
            LoadForm(); //Gọi phương thức đưa dữ liệu lên form.
        }

        private void dgvdocgia_SelectionChanged(object sender, EventArgs e)
        {
            if (dgvdocgia.SelectedRows.Count > 0) //Nếu trong DataGrid có từ 1 dòng trở lên.
            {
                txtmathe.Text = dgvdocgia.SelectedRows[0].Cells["MATHE"].Value.ToString(); //Chọn dòng đầu tiên, ô thứ 1.
                txthoten.Text = dgvdocgia.SelectedRows[0].Cells["HOTEN"].Value.ToString(); //Chọn dòng đầu tiên, ô thứ 2.
                cbogioitinh.Text = dgvdocgia.SelectedRows[0].Cells["GIOITINH"].Value.ToString().Trim();
                txtdiachi.Text = dgvdocgia.SelectedRows[0].Cells["DIACHI"].Value.ToString();
                txtngaysinh.Text = dgvdocgia.SelectedRows[0].Cells["NGAYSINH"].Value.ToString();
                cboloaidg.Text = dgvdocgia.SelectedRows[0].Cells["TENLDG"].Value.ToString();
                cbotinhtrang.Text = dgvdocgia.SelectedRows[0].Cells["TINHTRANGNO"].Value.ToString();
                txtngaylapthe.Text = dgvdocgia.SelectedRows[0].Cells["NGAYLAPTHE"].Value.ToString();
                txtngayhethan.Text = dgvdocgia.SelectedRows[0].Cells["NGAYHETHAN"].Value.ToString();
                txttongno.Text = dgvdocgia.SelectedRows[0].Cells["TONGNO"].Value.ToString();
                String duongdanhinh = dgvdocgia.SelectedRows[0].Cells["HINHANH"].Value.ToString();

                // pchinh.Show();
                String url = Application.StartupPath + @"\" + duongdanhinh;
                if (System.IO.File.Exists(url))
                {
                    pchinh.ImageLocation = url;
                }
                else
                    pchinh.ImageLocation = null;
            }
        }

        private void btnthoat_Click(object sender, EventArgs e)
        {
            DialogResult dlg = new DialogResult();
            dlg = DevComponents.DotNetBar.MessageBoxEx.Show("Có muốn thoát không ?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dlg == DialogResult.Yes)
            {
                this.Close();
            }
        }

        private void btnsua_Click(object sender, EventArgs e)
        {
            if (btnsua.Text == "Sửa")
            {
                NutSua(); //Khi nhấn nút sửa.
            }
            else
            {
                NutHuyBoSua(); //Khi nhấn nút hủy bỏ sửa.
            }
        }

        private void btnluu_Click(object sender, EventArgs e)
        {            
            SuaDocGia(); //Gọi phương thức sửa thể loại.
        }

        private void btnxoa_Click(object sender, EventArgs e)
        {
            DocGiaDTO = new clsDocGiaDTO(); //Khởi tạo đối tượng.
            //--------------------------------
            DocGiaDTO.MaThe = txtmathe.Text.Trim(); //Lấy dữ liệu.
            //--------------------------------

            XoaDocGia(); //Gọi phương thức xóa thể loại.
        }

        private void btnchonhinh_Click(object sender, EventArgs e)
        {
            LayHinh(); //Gọi phương thức lấy hình.
        }

        private void btntim_Click(object sender, EventArgs e)
        {
            TimDocGia(); //Gọi phương thức tìm độc giả trên GridView.
        }
        #endregion

        private void groupPanel1_Click(object sender, EventArgs e)
        {

        }
    }
}